package com.tanhua.admin.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.tanhua.model.vo.AnalysisSummaryVo;
import com.tanhua.model.vo.SummryOfDay;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author lxb哦吼吼
 * @version 1.0
 * @description: TODO
 * @date 2021/11/25 17:22
 */

@Service
public class DashboardService {

    @Autowired
    private AnalysisService analysisService;

    public AnalysisSummaryVo getSummary(String dateTimeString) {

        AnalysisSummaryVo analysisSummaryVo = new AnalysisSummaryVo();

        DateTime dateTime = DateUtil.parseDate(dateTimeString);

        //累计用户数
        analysisSummaryVo.setCumulativeUsers(Long.valueOf(1000));

        //过去30天活跃用户
        analysisSummaryVo.setActivePassMonth(analysisService.queryActiveUserCount(dateTime, offsetDay(dateTime, -30)));

        //过去7天活跃用户
        analysisSummaryVo.setActivePassWeek(analysisService.queryActiveUserCount(dateTime, offsetDay(dateTime, -7)));

        //今日活跃用户
        analysisSummaryVo.setActiveUsersToday(analysisService.queryActiveUserCount(dateTime, dateTime));


        //今日新增用户
        analysisSummaryVo.setNewUsersToday(analysisService.queryRegisterUserCount(dateTime, dateTime));

        //今日新增用户涨跌率，单位百分数，正数为涨，负数为跌
        analysisSummaryVo.setNewUsersTodayRate(computeRate(
                analysisSummaryVo.getNewUsersToday(),
                this.analysisService.queryRegisterUserCount(dateTime, offsetDay(dateTime, -1))
        ));

        //今日登录次数
        analysisSummaryVo.setLoginTimesToday(this.analysisService.queryLoginUserCount(dateTime, dateTime));

        //今日登录次数涨跌率，单位百分数，正数为涨，负数为跌
        analysisSummaryVo.setLoginTimesTodayRate(computeRate(
                analysisSummaryVo.getLoginTimesToday(),
                this.analysisService.queryLoginUserCount(dateTime, offsetDay(dateTime, -1))
        ));

        analysisSummaryVo.setActiveUsersTodayRate(computeRate(
                analysisSummaryVo.getActiveUsersToday(),
                this.analysisService.queryActiveUserCount(dateTime, offsetDay(dateTime, -1))
        ));
        return analysisSummaryVo;
    }

    /**
     * 计算百分比
     *
     * @param current
     * @param last
     * @return
     */
    private static BigDecimal computeRate(Long current, Long last) {
        BigDecimal result;
        if(last == null){
            return BigDecimal.valueOf(0);
        }
        if (last == 0) {
            // 当上一期计数为零时，此时环比增长为倍数增长
            result = new BigDecimal((current - last) * 100);
        } else {
            result = BigDecimal.valueOf((current - last) * 100).divide(BigDecimal.valueOf(last), 2, BigDecimal.ROUND_HALF_DOWN);
        }
        return result;
    }

    /**
     * 计算偏差时间
     *
     * @param date
     * @param offSet
     * @return
     */
    private static DateTime offsetDay(Date date, int offSet) {
        return DateUtil.offsetDay(date, offSet);
    }

    /**
     * 统计新增、活跃用户、次日留存率,抽取
     *
     * @param sd
     * @param ed
     * @param type
     * @return
     */
    private List<SummryOfDay> getSummryList(DateTime sd, DateTime ed, String type) {
        ArrayList<SummryOfDay> summryOfDays = new ArrayList<>();
        Long aLong;
        if (type.equals("101")) {
            aLong = analysisService.queryRegisterUserCount(sd, sd);
        } else if (type.equals("102")) {
            aLong = analysisService.queryActiveUserCount(sd, sd);
        } else {
            aLong = analysisService.queryRetention1dCount(sd, sd);
        }
        summryOfDays.add(new SummryOfDay(sd.toDateStr(), aLong == null ? 0 : Integer.valueOf(aLong.toString())));
        //循坏
        int count = 1;
        while (true) {
            DateTime next = DateUtil.offsetDay(sd, count);
            if (hasNext(next, ed)) {
                Long sum;
                if (type.equals("101")) {
                    sum = analysisService.queryRegisterUserCount(next, next);
                } else if (type.equals("102")) {
                    sum = analysisService.queryActiveUserCount(next, next);
                } else {
                    sum = analysisService.queryRetention1dCount(next, next);
                }
                summryOfDays.add(new SummryOfDay(next.toDateStr(), sum ==null ? 0 : Integer.valueOf(sum.toString())));
                count++;
                continue;
            }
            break;
        }
        return summryOfDays;
    }

    private Boolean hasNext(DateTime sd, DateTime ed) {
        DateTime next = DateUtil.offsetDay(sd, 1);
        int i = next.toString("yyyyddmm").compareTo(ed.toString("yyyyddmm"));
        return i <= 0 ? true : false;
    }

    public Map<String, List> getUsers(DateTime sd, DateTime ed, String type) {
        List<SummryOfDay> summryList = this.getSummryList(sd, ed, type);
        DateTime sd1 = DateUtil.offsetMonth(sd, 12);
        DateTime ed1 = DateUtil.offsetMonth(ed, 12);
        List<SummryOfDay> summryList1 = this.getSummryList(sd1, ed1, type);
        Map<String, List> stringListMap = new HashMap<String, List>(2);
        stringListMap.put("thisYear", summryList);
        stringListMap.put("lastYear", summryList1);
        return stringListMap;
    }
}
